package com.example.occlusiondemo.view;

import static com.example.occlusiondemo.Status.editedParameter;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.opengl.GLSurfaceView;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;

import com.eqgis.eqtool.tmp.VibrateHelper;
import com.example.occlusiondemo.R;
import com.example.occlusiondemo.layout.LayoutUtils;
import com.example.occlusiondemo.layout.func.ExcavatorManager;
import com.supermap.ar.areffect.AREffectView;
import com.supermap.data.GeoPoint;
import com.supermap.data.GeoRegion;
import com.supermap.data.Geometrist;
import com.supermap.data.Point2D;
import com.supermap.data.Point2Ds;

import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * 动态视图
 * <pre>
 *     用于绘制屏幕裁剪的轮廓线,以及手势管理
 *     底层->顶层的层级顺序
 *     AREffectView -> DynamicView -> UI按钮
 *
 *     备注：
 *     version 2.0的需求：
 *     视口模式下：
 * </pre>
 *
 * @author tanyx 2022/9/22
 * @version 1.0
 **/
public class DynamicView extends GLSurfaceView implements View .OnTouchListener,Runnable{

    public final String TAG = DynamicView.class.getSimpleName();
    private Paint paint;
    private Paint selectPaint;

    private Executor executor;


    /**
     * 执行屏幕裁剪的实时点集
     */
    private ArrayList<int[]> points = new ArrayList<>();
    private AREffectView view;
    private Paint selectPaint2;
    private ArrayList<int[]> points2 = new ArrayList<>();;
    private float radius = 20;

    public DynamicView(Context context) {
        super(context);
        init();
    }

    public DynamicView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint = new Paint();
//        paint.setColor(((0xff << 129) | (255<<129) | (255<<129) | 129));
        paint.setColor(((0xff << 24) | (130<<16) | (130<<8) | 130));
        paint.setStrokeWidth(2);

        selectPaint = new Paint();
        selectPaint.setColor(((0xff << 24) | (3<<16) | (240<<8) | 240));
        selectPaint.setStrokeWidth(12);
        selectPaint2 = new Paint();
        selectPaint2.setColor(((0xff << 24) | (3<<16) | (240<<8) | 240));
        selectPaint2.setStrokeWidth(6);
        selectPaint2.setPathEffect(new DashPathEffect(new float[]{20, 20}, 0));

        getHolder().setFormat(PixelFormat.TRANSLUCENT);
        setOnTouchListener(this);

        DigGestureManager.getInstance().setDigGestureCallback(new DigGestureManager.DigGestureCallback() {
            @Override
            public boolean onDoubleTap(MotionEvent event) {
                Log.d(TAG, "IKKYU-DEBUG onDoubleTap: DYNAMIC_VIEW");
                return true;
            }

            @Override
            public void onShowPress(MotionEvent e) {
//                Toast.makeText(getContext(), "单指”上下滑动“修改深度值", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public synchronized void clear(){
        try {
            SurfaceHolder holder = getHolder();
            Canvas canvas = holder.lockCanvas();
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            holder.unlockCanvasAndPost(canvas);
        }catch (Exception e){}
    }

    public synchronized void updateLine(ArrayList<int[]> points){
        this.points = points;
        if (points == null || points.size() == 0){
            clear();
            return;
        }

        try {
            Paint tmpPaint;
            if (editedParameter){
                tmpPaint = selectPaint;
            }else {
                tmpPaint = paint;
            }
            SurfaceHolder holder = getHolder();
            Canvas canvas = holder.lockCanvas();
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            if (points.size()>1){
                float[] pts = new float[points.size() * 4 - 4];
                for (int i = 0; i < points.size() - 1; i++) {
                    int[] ints = points.get(i);
                    int[] ints1 = points.get(i + 1);
                    pts[4 * i] = ints[0];
                    pts[4 * i + 1] = ints[1];
                    pts[4 * i + 2] = ints1[0];
                    pts[4 * i + 3] = ints1[1];

                    canvas.drawCircle(ints[0],ints[1],3,tmpPaint);
                }
                canvas.drawLines(pts,tmpPaint);
                holder.unlockCanvasAndPost(canvas);
            }
        }catch (Exception e){}
    }

    public synchronized ArrayList<int[]> updateLine(ArrayList<int[]> p1,ArrayList<int[]> p2){
        points.clear();
        points2.clear();
        if (p1!=null){
            for (int i = 0; i < p1.size(); i++) {
                points.add(p1.get(i));
            }
        }
        if (p2!=null){
            for (int i = 0; i < p2.size(); i++) {
                points2.add(p2.get(i));
            }
        }
        if (executor == null){
             executor = Executors.newSingleThreadExecutor();
        }
        executor.execute(this::run);
        return points;
    }

    private long downTime;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (points == null)return false;
        if (view == null){
            throw new NullPointerException("connectView failed!");
        }

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                downTime = SystemClock.currentThreadTimeMillis();
                editedParameter = false;
                break;
            case MotionEvent.ACTION_MOVE:
                if (!editedParameter){
                    if (SystemClock.currentThreadTimeMillis() - 200 > downTime){
                        editedParameter = true;
                        VibrateHelper.vSimple(getContext(),75);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                VibrateHelper.vSimple(getContext(),75);
                //清除编辑状态时绘制的内容
                clear();
                editedParameter = false;
                break;
        }

        /**
         * 说明：
         * 手势点位置
         * 若在坑洞内，则使用AR场景的交互手势
         * 若在坑洞外，则使用修改开挖参数的手势
         */
        return onTap(event);
    }

    //属性查询的点击事件
    public boolean onTap(MotionEvent event){
        //在执行属性查询（单指点击 事件），防止触碰到开挖范围外的管线模型
        Point2Ds targetP2s = new Point2Ds();
        for (int i = 0; i < points.size(); i++) {
            int[] point = points.get(i);
            targetP2s.add(new Point2D(point[0],point[1]));
        }
        if (targetP2s.getCount()<3){
            return true;
        }
        GeoRegion target = new GeoRegion(targetP2s);

        /**
         * Geometrist#isWithin(Geometry geometrySearch, Geometry geometryTarget)
         * 判断搜索几何对象是否在被搜索几何对象内。
         */
        GeoPoint geoPoint = new GeoPoint(event.getX(), event.getY());
        boolean within = Geometrist.isWithin(geoPoint, target);
        if (within && ExcavatorManager.getInstance().isLock()){
            return view.getArSceneView().onTouchEvent(event);
        }else {
            return DigGestureManager.getInstance().onTouchEvent(event);
//            if (!ExcavatorManager.getInstance().isLock()){
//                return DigGestureManager.getInstance().onTouchEvent(event);
//            }else {
//                return false;
//            }
        }

//        return DigGestureManager.getInstance().onTouchEvent(event);
    }

    public void connectView(AREffectView arView) {
        this.view = arView;
    }

    @Deprecated
    @Override
    public void run() {
        /**
         * lxk需求，天花板，墙面，地板，要用不同的颜色边框表示
         */
        switch (ExcavatorManager.getInstance().getFlag()){
            case /*地板开挖的边框*/0:
                paint.setColor(((0xff << 24) | (60<<16) | (60<<8) | 60));
                break;
            case /*墙面*/1:
                paint.setColor(((0xff << 24) | (62<<16) | (36<<8) | 35));
                break;
            case /*天花板*/2:
                paint.setColor(((0xff << 24) | (90<<16) | (90<<8) | 90));
                break;
        }

        if (points == null || points.size() == 0){
            clear();
            return;
        }

        Paint tmpPaint;
        float tmpRadius;
        if (LayoutUtils.getClickStatus(R.id.icon_tool_outline)){
            //根据最新的产品要求， 此处轮廓线的显示由按钮开关控制了。2022年10月24日
//        if (editedParameter){
            tmpPaint = selectPaint;
            tmpRadius = 6;
        }else {
            tmpPaint = paint;
            tmpRadius = radius;
        }
        SurfaceHolder holder = getHolder();
        Canvas canvas = holder.lockCanvas();
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        if (points.size()>1){
            float[] pts = new float[points.size() * 4 - 4];
            for (int i = 0; i < points.size() - 1; i++) {
                int[] ints = points.get(i);
                int[] ints1 = points.get(i + 1);
                pts[4 * i] = ints[0];
                pts[4 * i + 1] = ints[1];
                pts[4 * i + 2] = ints1[0];
                pts[4 * i + 3] = ints1[1];
                canvas.drawCircle(ints[0],ints[1],tmpRadius,tmpPaint);
            }
            canvas.drawLines(pts,tmpPaint);


            try {
                if (points2!=null && points2.size() != 0){
                    for (int i = 0; i < points2.size() - 1; i++) {
                        int[] ints = points2.get(i);
                        int[] ints1 = points2.get(i + 1);
                        pts[4 * i] = ints[0];
                        pts[4 * i + 1] = ints[1];
                        pts[4 * i + 2] = ints1[0];
                        pts[4 * i + 3] = ints1[1];
                    }
                    canvas.drawLines(pts,selectPaint2);
//                    canvas.drawLine(points.get(0)[0],points.get(0)[1],points2.get(1)[0],points2.get(1)[1],selectPaint2);
//                    canvas.drawLine(points.get(1)[0],points.get(1)[1],points2.get(2)[0],points2.get(2)[1],selectPaint2);
//                    canvas.drawLine(points.get(2)[0],points.get(2)[1],points2.get(3)[0],points2.get(3)[1],selectPaint2);
//                    canvas.drawLine(points.get(3)[0],points.get(3)[1],points2.get(0)[0],points2.get(0)[1],selectPaint2);
                    //更新标注
//                    CalloutManager.getInstance().updateCallout(canvas,true);
                }
            }catch (RuntimeException e){

            }
            holder.unlockCanvasAndPost(canvas);
        }
    }

    /**
     * 设置点范围
     * <p>在每次屏幕裁剪点计算后，调用本方法</p>
     * @param screenPoint 屏幕裁剪点
     */
    public DynamicView setPoints(ArrayList<int[]> screenPoint) {
        this.points = screenPoint;
        return this;
    }

}
